import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;



import java.util.logging.Logger;

import com.acme.bankapp.domain.Bank;
import com.acme.bankapp.service.BankService;
import com.acme.bankapp.domain.Gender;

public class BankServer {
	static Bank bank = new Bank();
    public static final Logger log = Logger.getLogger(BankServer.class.getName());
    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws IOException, InterruptedException {
		BankService service = new BankService();
        final BlockingQueue<String> queueTask = new LinkedBlockingQueue<String>();
        int counter = 0;
        try {
			String s1 = "accounttype=s;balance=1000000;overdraft=1000000;firstname=A;lastname=A1;gender=m;";
			String s2 = "accounttype=s;balance=11;overdraft=70;firstname=B;lastname=B1;gender=f;";
			String s3 = "accounttype=s;balance=10;overdraft=12;firstname=C;lastname=C1;gender=m;";
			String s4 = "accounttype=s;balance=10;overdraft=0;firstname=D;lastname=D1;gender=m;";
			PrintWriter out = new PrintWriter(new BufferedWriter (new FileWriter(args[0])));
			out.println(s1);
			out.println(s2);
			out.println(s3);
			out.println(s4);
			out.close();
		}
		catch (Exception e) {
			log.info("Error");
			return;
		}
		try {
			BufferedReader in = new BufferedReader(new FileReader(args[0]));
			String data = new String();
			do {
				data = in.readLine();
				if (data != null) {
					service.addClient(bank, data);
                    log.info("Client was added");
				}
			} while (data != null);
			in.close();
		}
		catch (IOException e) {
			log.warning("Error in reading the file");
			return;
		}
            log.info("Start listening");
            System.out.println("Start listening");
            new Thread() {
                @Override
                public void run() {
                    ServerSocket s = null;
                    try {
                        s = new ServerSocket(90);
                        Socket fromClient = s.accept();
                        String resultInput;
                        BufferedReader in = new BufferedReader(new InputStreamReader(fromClient.getInputStream()));
                        ObjectOutputStream out = new ObjectOutputStream(fromClient.getOutputStream());
                        while (true) {
                            resultInput = in.readLine();
                            if (resultInput != null) {
                                try {
                                    queueTask.put(resultInput);
                            //        log.info("RESULTINPUT "+resultInput);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            new Thread() {
                @Override
                public void run() {
                    ServerSocket s = null;
                    try {
                        s = new ServerSocket(91);
                        Socket fromClient = s.accept();
                        String resultInput;
                        BufferedReader in = new BufferedReader(new InputStreamReader(fromClient.getInputStream()));
                        ObjectOutputStream out = new ObjectOutputStream(fromClient.getOutputStream());
                        while (true) {
                            resultInput = in.readLine();
                            if (resultInput != null) {
                                try {
                                    queueTask.put(resultInput);
                          //          log.info("RESULTINPUT "+resultInput);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        while (true) {
            if (queueTask.isEmpty()) {
                continue;
            }
            String resultInput = queueTask.take();
			StringTokenizer strResult = new StringTokenizer(resultInput,";");
			String helpString = strResult.nextToken();
			int index = resultInput.indexOf(';');
			String data = resultInput.substring(index + 1);
			if (helpString.equals("add")) {
				service.addClient(bank, data);
				log.info("Current time after add: "+System.currentTimeMillis());
				//service.printAllClients(bank);
				counter++;
				log.info("Counter = "+counter);
			}
			else 
				if (helpString.equals("printall")) {
					service.printAllClients(bank);
				}
				else
                    if (helpString.equals("withdraw")) {
                        String firstName = strResult.nextToken();
                        firstName = firstName.substring(firstName.indexOf('=') + 1);
                        String lastName = strResult.nextToken();
                        lastName = lastName.substring(lastName.indexOf('=') + 1);
                        String gender = strResult.nextToken();
                        gender = gender.substring(gender.indexOf('=') + 1);
                        Gender gen;
                        if (gender.equals("m")) {
                            gen = Gender.MALE;
                        } else {
                            gen = Gender.FEMALE;
                        }
                        service.withdrawClient(bank,firstName, lastName, gen, Double.parseDouble(strResult.nextToken()));
                        log.info("Current time after withdraw: "+System.currentTimeMillis());
                    }
                    else 
                        if (helpString.equals("delete")) {
                        	String firstName = strResult.nextToken();
                            firstName = firstName.substring(firstName.indexOf('=') + 1);
                            String lastName = strResult.nextToken();
                            lastName = lastName.substring(lastName.indexOf('=') + 1);
                            String gender = strResult.nextToken();
                            gender = gender.substring(gender.indexOf('=') + 1);
                            Gender gen;
                            if (gender.equals("m")) {
                                gen = Gender.MALE;
                            } else {
                                gen = Gender.FEMALE;
                            }
                            service.deleteClient(bank,firstName, lastName, gen);
                            log.info("Current time after delete: "+System.currentTimeMillis());
                        }
                        else {
					        log.info("There is no such comand");
                        }
        }
    }
}